import * as fs from 'fs';
import * as path from 'path';

// 检测文件(夹)是否存在
export function isExist(filePath: string): boolean {
  try {
    fs.accessSync(filePath, fs.constants.R_OK); // 可读且存在
    return true;
  } catch (e) {
    return false;
  }
}

// 检测是否是一个文件路径
export function isFile(filePath: string): boolean {
  if (!fs.existsSync(filePath)) return false;
  try {
    const stat = fs.statSync(filePath);
    return stat.isFile();
  } catch (e) {
    return false;
  }
}

// 检测是否是一个文件夹路径
export function isDirectory(filePath: string): boolean {
  if (!fs.existsSync(filePath)) return false;
  try {
    const stat = fs.statSync(filePath);
    return stat.isDirectory();
  } catch (e) {
    return false;
  }
}

// 修改文件(夹)权限，所有者、组成员、其他用户(r=4,w=2,x=1)
export function chmod(filePath: string, mode = 0o755): boolean {
  try {
    fs.chmodSync(filePath, mode);
    return true;
  } catch (e) {
    return false;
  }
}

// 创建文件夹
export function mkdir(filePath: string): boolean {
  if (isExist(filePath)) {
    return true;
  }
  const dir = path.dirname(filePath);
  if (!isExist(dir)) {
    try {
      fs.mkdirSync(dir, { recursive: true, mode: 0o755 });
      chmod(dir);
      return true;
    } catch (e) {
      return false;
    }
  }
  return true;
}

// 写入文件内容
export function writeFileSync(filePath: string, content: string): boolean {
  if (mkdir(filePath)) {
    fs.writeFileSync(filePath, content, { flag: 'w' });
    chmod(filePath);
    return true;
  }
  return false;
}

// 读取文件内容
export function readFileSync(fullPath: string, toJson?: boolean): string | object {
  if (!isExist(fullPath)) {
    return '';
  }
  try {
    let content = fs.readFileSync(fullPath, { encoding: 'utf-8' });
    if (toJson) {
      content = JSON.parse(content);
    }
    return content;
  } catch (error) {
    return '';
  }
}

// 读取文件夹所有文件
export function listFilesRecursively(dir: string, ext: string, excludes: string[]): string[] {
  const files: string[] = [];
  const dirFiles = fs.readdirSync(dir);
  const exc = (excludes || []).map((t) => path.join(dir, t));
  dirFiles.forEach((item) => {
    const fullPath = path.join(dir, item);
    const stats = fs.lstatSync(fullPath);
    const regex = new RegExp(`(${ext.split(',').join('|')})$`);
    if (stats.isDirectory()) {
      files.push(...listFilesRecursively(fullPath, ext, excludes));
    } else if (regex.test(item) && !exc.includes(fullPath)) {
      files.push(fullPath);
    }
  });
  return files;
}

// 删除文件夹所有文件
export function deleteFilesRecursively(dir: string, ext: string, excludes: string[]): void {
  const dirFiles = fs.readdirSync(dir);
  const exc = (excludes || []).map((t) => path.join(dir, t));
  dirFiles.forEach((item) => {
    const fullPath = path.join(dir, item);
    const stats = fs.lstatSync(fullPath);
    const regex = new RegExp(`(${ext.split(',').join('|')})$`);
    if (stats.isDirectory()) {
      deleteFilesRecursively(fullPath, ext, excludes);
    } else if (regex.test(item) && !exc.includes(fullPath)) {
      fs.unlinkSync(fullPath);
    }
  });
}
